package com.pactera.asmp.server.common.threadpool.workqueue;

import com.pactera.asmp.server.common.threadpool.IWorkTask;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.concurrent.*;

/**
 * <p>Class: com.lzq.plugin.threadpool.workqueue.NetWorkThreadPoolExecutor</p>
 * <p>Description: </p>
 * <pre>
 *
 * </pre>
 *
 * @author lv zhiqiang
 * @date 2019/7/17/11:21
 */
public class WorkThreadPoolExecutor  extends ThreadPoolExecutor {
    private static final Logger logger = LoggerFactory.getLogger(WorkThreadPoolExecutor().getClass());
    private static WorkThreadPoolExecutor mWorkThreadPoolExecutor;
    protected  static int mCorePoolSize = 5;
    protected  static int mMaximumPoolSize = 6;
    protected  static int mKeepAlivewTime = 10 * 1000;
    protected  static TimeUnit mTimeUnit = TimeUnit.MILLISECONDS;
    protected  static BlockingQueue<Runnable> mWorkQueue = new ArrayBlockingQueue<>(20);
    protected  static WrokThreadFactory mWrokThreadFactory = new WrokThreadFactory();
    protected  static WorkThreadRejectedExecutionHandler mWorkThreadRejectedExecutionHandler = new WorkThreadRejectedExecutionHandler();

    private static WorkThreadPoolExecutor WorkThreadPoolExecutor(){
        mWorkThreadPoolExecutor = new WorkThreadPoolExecutor(mCorePoolSize, mMaximumPoolSize, mKeepAlivewTime, mTimeUnit, mWorkQueue, mWrokThreadFactory, mWorkThreadRejectedExecutionHandler);
        return mWorkThreadPoolExecutor;
    }

    private WorkThreadPoolExecutor(int corePoolSize, int maximumPoolSize, long keepAliveTime, TimeUnit unit, BlockingQueue<Runnable> workQueue, ThreadFactory threadFactory, RejectedExecutionHandler handler) {
        super(corePoolSize, maximumPoolSize, keepAliveTime, unit, workQueue, threadFactory, handler);
    }

    /**
     * getInstance
     * @return WorkThreadPoolExecutor
     */
    public static WorkThreadPoolExecutor getInstance(){
        if(mWorkThreadPoolExecutor == null){
            synchronized ("getInstance"){
                mWorkThreadPoolExecutor = WorkThreadPoolExecutor();
                mWorkThreadPoolExecutor.prestartAllCoreThreads();
            }
        }
        return mWorkThreadPoolExecutor;
    }

    /**
     * executorTask
     * @param task
     * @return
     */
    public <T extends IWorkTask> WorkThreadPoolExecutor executorTask(T task){
       mWorkThreadPoolExecutor.execute(task);
        return mWorkThreadPoolExecutor;
    }

    /**
     * executorTask
     * @param runnable
     * @return
     */
    public WorkThreadPoolExecutor executorTask(Runnable runnable){
        mWorkThreadPoolExecutor.execute(runnable);
        return mWorkThreadPoolExecutor;
    }
}
